import { ExtractPropTypes, PropType } from "vue"

/**
 * 已上传文件列表类型
 */
export type ImageUploadUserFile = {
  /** 图片地址 */
  url: string,
  [prop: string]: any
}

/**
 * 文件列表数据类型
 */
export type ImageUploadList = {
  /** 图片地址 */
  url?: string,
  /** 请求返回的数据 */
  data?: any,
  /** 上传进度 */
  progress?: number,
  /** 上传错误标识 */
  error?: boolean,
  /** 上传处理对象 */
  task?: UniApp.UploadTask | null,
  /** 文件对象 */
  file?: UniApp.ChooseImageSuccessCallbackResult['tempFiles']
}

/**
 * 选择图片sizeType有效值
 */
export const ImageUploadSizes = ['original', 'compressed'] as const
export type ImageUploadSize = typeof ImageUploadSizes[number]

/**
 * 图片来源有效值
 */
export const ImageUploadSources = ['album', 'camera'] as const
export type ImageUploadSource = typeof ImageUploadSources[number]

/**
 * 上传前执行函数类型
 */
export type BeforeUploadParams = (file: ImageUploadList, index: number) => void

/**
 * 删除前执行函数类型
 */
export type BeforeRemoveParams = (file: ImageUploadList, index: number) => void

/**
 * props参数
 */
export const imageUploadProps = {
  /** 已上传的文件列表 */
  fileList: {
    type: Array as PropType<Array<ImageUploadUserFile>>,
    default: (): ImageUploadUserFile[] => {
      return []
    }
  },
  /** 禁止上传 */
  disabled: {
    type: Boolean,
    default: false
  },
  /** 上传地址 */
  action: {
    type: String,
    required: true
  },
  /** 上传文件字段名称 */
  name: {
    type: String,
    default: 'file'
  },
  /** HTTP 请求 Header, header 中不能设置 Referer */
  header: {
    type: Object,
    default: () => {
      return {}
    }
  },
  /** HTTP 请求中其他额外的 form data */
  formData: {
    type: Object,
    default: () => {
      return {}
    }
  },
  /** 自动上传 */
  autoUpload: {
    type: Boolean,
    default: true
  },
  /** 最大上传数量 */
  limit: {
    type: Number,
    default: 9
  },
  /** 显示删除按钮 */
  showDelete: {
    type: Boolean,
    default: true
  },
  /** 显示操作提示信息 */
  showTips: {
    type: Boolean,
    default: true
  },
  /** 显示上传进度 */
  showProgress: {
    type: Boolean,
    default: true
  },
  /** 
   * 选择图片的尺寸
   * https://uniapp.dcloud.io/api/media/image.html
   */
  sizeType: {
    type: Array as PropType<ImageUploadSize[]>,
    default: (): ImageUploadSize[] => {
      return ['original', 'compressed']
    }
  },
  /** 
   * 选择图片的来源 
   * https://uniapp.dcloud.io/api/media/image.html
   */
  sourceType: {
    type: Array as PropType<ImageUploadSource[]>,
    default: (): ImageUploadSource[] => {
      return ['album', 'camera']
    }
  },
  /** 允许多选 */
  multiple: {
    type: Boolean,
    default: true
  },
  /** 最大允许上传文件大小, 单位byte */
  maxSize: {
    type: Number,
    default: 10 * 1024 * 1024
  },
  /** 允许上传的文件后缀 */
  limitType: {
    type: Array as PropType<string[]>,
    default: (): string[] => {
      return ['jpg', 'png', 'jpeg', 'webp', 'gif', 'ico']
    }
  },
  /** 上传前执行的钩子函数 */
  beforeUpload: {
    type: Function,
    default: undefined
  },
  /** 移除前执行的钩子函数 */
  beforeRemove: {
    type: Function,
    default: undefined
  },
  /** 组件标识 */
  index: {
    type: [String, Number],
    default: ''
  }
}
export type ImageUploadProps = ExtractPropTypes<typeof imageUploadProps>

export const imageUploadEmits = {
  /** 列表数据发生改变时触发 */
  'list-change': (files: ImageUploadList[], index: string | number) => true,
  /** 选择的文件操作最大允许上传大小时触发 */
  oversize: (file: UniApp.ChooseImageSuccessCallbackResult['tempFiles'], index: string | number) => true,
  /** 选择的文件数量超过最大限制时触发 */
  exceed: (index: string | number) => true,
  /** 文件选择完成时触发 */
  'choose-complete': (files: ImageUploadList[], index: string | number) => true,
  /** 文件选择失败时触发 */
  'choose-fail': (err: any, index: string | number) => true,
  /** 文件上传完成时触发 */
  uploaded: (files: ImageUploadList[], index: string | number) => true,
  /** 文件上传成功时触发 */
  success: (response: any, uploadFile: ImageUploadList, uploadFiles: ImageUploadList[], index: string | number) => true,
  /** 文件上传失败时触发 */
  error: (err: any, uploadFile: ImageUploadList, uploadFiles: ImageUploadList[], index: string | number) => true,
  /** 文件状态修改时触发, 上传成功、上传失败 */
  change: (uploadFile: ImageUploadList, uploadFiles: ImageUploadList[], index: string | number) => true,
  /** 文件上传进度发生修改时触发 */
  progress: (event: any, uploadFiles: ImageUploadList[], index: string | number) => true,
  /** 文件移除时触发 */
  remove: (uploadFile: ImageUploadList, uploadFiles: ImageUploadList[], index: string | number) => true,
  /** 文件点击预览时触发 */
  preview: (uploadFile: ImageUploadList, uploadFiles: ImageUploadList[], index: string | number) => true,
}
export type ImageUploadEmits = typeof imageUploadEmits
